<!-- 修改密码弹窗 -->
<script lang="tsx">
import { defineComponent, ref, computed, reactive, nextTick, watch } from 'vue';
import { $t } from '@vben/locales';
import { ElMessage } from 'element-plus';
import Code from '#/components/common/code.vue';
import { resetPasswordApi } from '#/api/core/auth';
import { changePasswordByOldPasswordApi } from '#/api/personal';
import { getVoiceVerificationCodeApi, getVerificationCodeApi } from '#/api/core/auth';
import setPublicCode from '#/utils/setPublicKey';
import { TelMatcher, PasswordRegex } from '#/utils/constants';
import { useCodeName } from '#/hooks/useCodeName';

export default defineComponent({
  name: 'ChangePasswordDialog',
  props: {
    modelValue: {
      type: Boolean,
      default: false,
    },
    currentPhone: {
      type: String,
      default: '',
    },
  },
  emits: ['update:modelValue', 'confirm'],
  setup(props, { emit }) {
    const passwordFormRef = ref();
    const smsFormRef = ref();
    const loading = ref(false);
    const activeTab = ref('password'); // 'password' 或 'sms'

    // 密码校验函数
    const passwordCheck = (val: string) => {
      return PasswordRegex.test(val);
    };
    const passwordErrMsg = $t('register.passwordFormatError');

    // 语音验证码相关
    const { isVoiceCode, codeBtnName, codeInputPlaceholder } = useCodeName();
    const codeRef = ref<any>(null);

    // 表单数据
    const passwordForm = reactive({
      oldPassword: '',
      newPassword: '',
      confirmPassword: ''
    });

    const smsForm = reactive({
      phone: props.currentPhone,
      verifyCode: '',
      newPassword: '',
      confirmPassword: ''
    });

    const visible = computed({
      get: () => props.modelValue,
      set: (val: boolean) => emit('update:modelValue', val)
    });

    // 监听选项卡切换，清除表单验证
    watch(activeTab, () => {
      nextTick(() => {
        // 清除密码表单验证
        passwordFormRef.value?.clearValidate();
        // 清除短信表单验证
        smsFormRef.value?.clearValidate();
      });
    });

    // 密码验证规则
    const passwordRules = {
      oldPassword: [
        { required: true, message: $t('personal.pleaseEnterOldPassword'), trigger: 'blur' },
      ],
      newPassword: [
        {
          required: true, validator: (rule: any, value: any, callback: any) => {
            if (!value) {
              callback(new Error($t('common.inputPhTxt', [$t('login.password')])));
              return;
            }
            if (!passwordCheck(value)) {
              callback(new Error(passwordErrMsg));
              return;
            }
            if (passwordForm.confirmPassword && value !== passwordForm.confirmPassword) {
              passwordFormRef.value?.validateField(['confirmPassword']);
            }

            // 验证通过，清除确认密码的错误并通过验证
            passwordFormRef.value?.clearValidate(['confirmPassword']);

            callback();
          }, trigger: 'blur'
        },
      ],
      confirmPassword: [
        {
          required: true, validator: (rule: any, value: any, callback: any) => {
            if (!value) {
              callback(new Error($t('common.inputPhTxt', [$t('register.confirmPassword')])));
              return;
            }
            if (!passwordCheck(value)) {
              callback(new Error(passwordErrMsg));
              return;
            }
            if (passwordForm.newPassword && value !== passwordForm.newPassword) {
              callback(new Error($t('register.passwordMismatchConfirmError')));
              return;
            }
            // 验证通过，清除登录密码的错误并通过验证
            passwordFormRef.value?.clearValidate(['newPassword']);
            callback();
          }, trigger: 'blur'
        }
      ]
    };

    // 短信验证规则
    const smsRules = {
      phone: [
        { required: true, pattern: TelMatcher, message: $t('common.phonePhTxt'), trigger: 'blur' },
      ],
      verifyCode: [
        { required: true, message: codeInputPlaceholder.value, trigger: 'blur' },
      ],
      newPassword: [
        {
          required: true, validator: (rule: any, value: any, callback: any) => {
            if (!value) {
              callback(new Error($t('common.inputPhTxt', [$t('login.password')])));
              return;
            }
            if (!passwordCheck(value)) {
              callback(new Error(passwordErrMsg));
              return;
            }
            if (smsForm.confirmPassword && value !== smsForm.confirmPassword) {
              smsFormRef.value?.validateField(['confirmPassword']);
            }

            // 验证通过，清除确认密码的错误并通过验证
            smsFormRef.value?.clearValidate(['confirmPassword']);

            callback();
          }, trigger: 'blur'
        },
      ],
      confirmPassword: [
        {
          required: true, validator: (rule: any, value: any, callback: any) => {
            if (!value) {
              callback(new Error($t('common.inputPhTxt', [$t('register.confirmPassword')])));
              return;
            }
            if (!passwordCheck(value)) {
              callback(new Error(passwordErrMsg));
              return;
            }
            if (smsForm.newPassword && value !== smsForm.newPassword) {
              callback(new Error($t('register.passwordMismatchConfirmError')));
              return;
            }
            // 验证通过，清除登录密码的错误并通过验证
            smsFormRef.value?.clearValidate(['newPassword']);
            callback();
          }, trigger: 'blur'
        }
      ]
    };

    // 获取短信验证码
    const getSmsCode = (callback: Function) => {
      smsFormRef.value?.validateField(['phone'], (valid: boolean) => {
        if (valid) {
          callback();
          if (isVoiceCode.value) {
            getVoiceVerificationCodeApi({ phoneNumber: smsForm.phone });
          } else {
            getVerificationCodeApi({ phoneNumber: smsForm.phone });
          }
        }
      });
    };

    // 切换语音验证码
    const getVoiceCode = (value: boolean, event?: Event) => {
      if (codeRef.value?.isCounting) return;
      // 阻止事件冒泡和默认行为，确保不触发任何表单相关事件
      if (event) {
        event.preventDefault();
        event.stopPropagation();
      }
      isVoiceCode.value = value;
      smsForm.verifyCode = '';
      // 清除验证码字段的验证错误
      smsFormRef.value?.clearValidate(['verifyCode']);
    };

    // 关闭弹窗
    const handleClose = () => {
      visible.value = false;
      // 重置表单
      passwordForm.oldPassword = '';
      passwordForm.newPassword = '';
      passwordForm.confirmPassword = '';
      smsForm.phone = props.currentPhone;
      smsForm.verifyCode = '';
      smsForm.newPassword = '';
      smsForm.confirmPassword = '';
      activeTab.value = 'password';
    };

    // 确认修改密码
    const handleConfirm = async () => {
      try {
        loading.value = true;

        let formValid = false;
        console.log(activeTab.value);
        if (activeTab.value === 'password') {
          formValid = await passwordFormRef.value.validate();
          if (formValid) {
            const data = {
              oldLoginPassword: setPublicCode(passwordForm.oldPassword) || '',
              newLoginPassword: setPublicCode(passwordForm.newPassword) || '',
            };
            await changePasswordByOldPasswordApi(data);
          }
        } else {
          formValid = await smsFormRef.value.validate();
          if (formValid) {
            const data = {
              phone: smsForm.phone,
              phoneCode: smsForm.verifyCode,
              loginPassword: setPublicCode(smsForm.newPassword) || '',
            };
            await resetPasswordApi(data);
          }
        }

        if (formValid) {
          ElMessage.success($t('personal.passwordChangedSuccess'));
          emit('confirm');
          handleClose();
        }
      } catch (error: any) {
      } finally {
        loading.value = false;
      }
    };

    return () => (
      <el-dialog
        v-model={visible.value}
        title={$t('personal.changePassword')}
        width="480px"
        onClose={handleClose}
        append-to-body
        destroy-on-close
        close-on-click-modal={false}
        class="change-password-dialog"
        v-slots={{
          footer: () => (
            <div class="flex justify-end">
              <el-button onClick={handleClose}>{$t('common.cancel')}</el-button>
              <el-button
                type="primary"
                onClick={handleConfirm}
                loading={loading.value}
              >
                {$t('common.confirm')}
              </el-button>
            </div>
          )
        }}
      >
        <div>
          <el-tabs v-model={activeTab.value} class="change-password-tabs">
            {/* 密码验证标签页 */}
            <el-tab-pane label={$t('personal.passwordVerification')} name="password">
              <el-form
                ref={passwordFormRef}
                model={passwordForm}
                rules={passwordRules}
                label-width="100px"
                label-position="right"
              >
                <el-form-item label={$t('personal.oldPassword')} prop="oldPassword">
                  <el-input
                    v-model={passwordForm.oldPassword}
                    maxlength={16}
                    type="password"
                    placeholder={$t('personal.pleaseEnterOldPassword')}
                    show-password
                    autocomplete="off"
                  />
                </el-form-item>
                <el-form-item label={$t('personal.newPassword')} prop="newPassword">
                  <el-input
                    v-model={passwordForm.newPassword}
                    maxlength={16}
                    type="password"
                    placeholder={$t('common.inputPhTxt', [$t('login.password')])}
                    show-password
                    autocomplete="off"
                  />
                </el-form-item>
                <el-form-item label={$t('personal.confirmNewPassword')} prop="confirmPassword">
                  <el-input
                    v-model={passwordForm.confirmPassword}
                    maxlength={16}
                    type="password"
                    placeholder={$t('common.inputPhTxt', [$t('register.confirmPassword')])}
                    show-password
                    autocomplete="off"
                  />
                </el-form-item>
              </el-form>
            </el-tab-pane>

            {/* 短信验证标签页 */}
            <el-tab-pane label={$t('personal.smsVerification')} name="sms">
              <el-form
                ref={smsFormRef}
                model={smsForm}
                rules={smsRules}
                label-width="110px"
                label-position="right"
              >
                <el-form-item label={$t('personal.phoneNumber')} prop="phone">
                  <el-input
                    v-model={smsForm.phone}
                    placeholder={$t('common.inputPhTxt', [$t('common.phoneTxt')])}
                    maxlength={11}
                    disabled
                  />
                </el-form-item>
                <el-form-item label={$t('personal.verificationCode')} prop="verifyCode">
                  <el-input
                    v-model={smsForm.verifyCode}
                    placeholder={codeInputPlaceholder.value}
                    maxlength={isVoiceCode.value ? 10 : 6}
                    minlength={3}
                    v-slots={{
                      append: () => (
                        <Code
                          ref={codeRef}
                          onGetCode={getSmsCode}
                          authCode={smsForm.phone}
                          codeName={codeBtnName.value}
                        />
                      )
                    }}
                  />
                </el-form-item>
                {smsForm.phone && (
                  <p class="text-[12px] text-[#595959] h-[10px] w-full text-right mt-1 mb-3">
                    {!isVoiceCode.value ? (
                      <>
                        {$t('login.noSmsCode')}
                        <span
                          class="text-[#0067D1] cursor-pointer"
                          onClick={(event) => getVoiceCode(true, event)}
                        >
                          {$t('login.voiceLogin')}
                        </span>
                      </>
                    ) : (
                      <span
                        class="text-[#0067D1] cursor-pointer"
                        onClick={(event) => getVoiceCode(false, event)}
                      >
                        {$t('login.switchSmsCode')}
                      </span>
                    )}
                  </p>
                )}
                <el-form-item label={$t('personal.newPassword')} prop="newPassword">
                  <el-input
                    v-model={smsForm.newPassword}
                    maxlength={16}
                    type="password"
                    placeholder={$t('common.inputPhTxt', [$t('login.password')])}
                    show-password
                    autocomplete="off"
                  />
                </el-form-item>
                <el-form-item label={$t('personal.confirmNewPassword')} prop="confirmPassword">
                  <el-input
                    v-model={smsForm.confirmPassword}
                    maxlength={16}
                    type="password"
                    placeholder={$t('common.inputPhTxt', [$t('register.confirmPassword')])}
                    show-password
                    autocomplete="off"
                  />
                </el-form-item>
              </el-form>
            </el-tab-pane>
          </el-tabs>
        </div>
      </el-dialog>
    );
  },
});
</script>

<style>
.change-password-dialog :deep(.el-form-item .el-form-item__label) {
  @apply pb-2 font-medium text-right;
}

.change-password-dialog :deep(.el-form-item .el-form-item__content) {
  @apply flex-1;
}

.change-password-tabs :deep(.el-tabs__header) {
  margin-bottom: 20px;
}

.change-password-tabs :deep(.el-tabs__nav-wrap::after) {
  display: none;
}
</style>
